package com.esapi.api;

import cn.hutool.json.JSONUtil;
import com.esapi.model.User;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;

import java.io.IOException;
import java.util.Date;

public class TestDocApi {

    private static RestHighLevelClient client;

    static {
        client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));
    }

    /**
     *  创建一个文档
     */
    public static void createDoc() throws IOException {

        IndexRequest request = new IndexRequest("user");

        User user = User.builder().id(1).name("jack").address("北京朝阳西坝河北里").sex(1).birthday(new Date()).build();
        request.source(JSONUtil.toJsonStr(user), XContentType.JSON);
        request.id(String.valueOf(user.getId()));

        IndexResponse response = client.index(request, RequestOptions.DEFAULT);

        System.out.println(JSONUtil.toJsonPrettyStr(response));
    }

    /**
     * 查询一个文档
     * @throws IOException
     */
    public static void queryDoc() throws IOException {

        GetRequest request = new GetRequest("user");

        request.index("user").id("1");

        GetResponse response = client.get(request, RequestOptions.DEFAULT);

        System.out.println(response.getSourceAsString());
    }

    /**
     *  更新文档
     * @throws IOException
     */
    public static void updateDoc() throws IOException {

        UpdateRequest request = new UpdateRequest();

        User user = User.builder().id(1).sex(2).build();

        request.index("user").id("1").doc(JSONUtil.toJsonStr(user), XContentType.JSON);

        UpdateResponse response = client.update(request, RequestOptions.DEFAULT);

        System.out.println(JSONUtil.toJsonPrettyStr(response));
    }

    /**
     *  删除一个文档
     * @throws IOException
     */
    public static void deleteDoc() throws IOException {

        DeleteRequest request = new DeleteRequest();

        request.index("user").id("gq_RhH4B5VG_RvDoXAVx");

        DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);

        System.out.println(JSONUtil.toJsonPrettyStr(response));
    }

    /**
     *  批量操作
     * @throws IOException
     */
    public static void batchRequest() throws IOException {

        BulkRequest request = new BulkRequest();

        request.add(new IndexRequest("user").id("2").source(JSONUtil.toJsonStr(User.builder().id(2).address("山东泰安").sex(1).birthday(new Date()).build()), XContentType.JSON));
        request.add(new IndexRequest("user").id("3").source(JSONUtil.toJsonStr(User.builder().id(3).address("山东济南").sex(2).birthday(new Date()).build()), XContentType.JSON));
        request.add(new IndexRequest("user").id("4").source(JSONUtil.toJsonStr(User.builder().id(4).address("山东济宁").sex(1).birthday(new Date()).build()), XContentType.JSON));

        request.add(new DeleteRequest("user").id("1"));

        BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);

        System.out.println(JSONUtil.toJsonPrettyStr(response));
    }


    /**
     *  全量查询
     */
    public static void queryMathAll() throws IOException {

        SearchRequest request = new SearchRequest();

        request.indices("user");

        request.source(SearchSourceBuilder.searchSource().query(QueryBuilders.matchAllQuery()));

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        for (SearchHit hit : response.getHits()) {
            System.out.println(hit.getSourceAsString());
        }
    }


    /**
     *  条件查询  termQuery
     */
    public static void queryMathWithCondition() throws IOException {

        SearchRequest request = new SearchRequest();

        request.indices("user");

        request.source(SearchSourceBuilder.searchSource().query(QueryBuilders.termQuery("sex", 2)));

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        for (SearchHit hit : response.getHits()) {
            System.out.println(hit.getSourceAsString());
        }
    }

    /**
     *  全量查询
     */
    public static void queryByPage() throws IOException {

        SearchRequest request = new SearchRequest();

        request.indices("user");

        request.source(SearchSourceBuilder
                .searchSource()
                .query(QueryBuilders.matchAllQuery())
                .from(0)
                .size(2)
        );

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        for (SearchHit hit : response.getHits()) {
            System.out.println(hit.getSourceAsString());
        }
    }

    /**
     *  组合查询
     */
    public static void queryByBool() throws IOException {

        SearchRequest request = new SearchRequest();

        request.indices("user");

        request.source(SearchSourceBuilder
                .searchSource()
                .query(QueryBuilders.boolQuery()
                        .must(QueryBuilders.matchQuery("address", "山东"))
                        .mustNot(QueryBuilders.matchQuery("sex", 2))
                )
        );

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        for (SearchHit hit : response.getHits()) {
            System.out.println(hit.getSourceAsString());
        }
    }

    /**
     *  范围查询
     */
    public static void queryByRange() throws IOException {

        SearchRequest request = new SearchRequest();

        request.indices("user");

        request.source(SearchSourceBuilder.searchSource().query(QueryBuilders.rangeQuery("sex").lte(1)));

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        for (SearchHit hit : response.getHits()) {
            System.out.println(hit.getSourceAsString());
        }
    }

    /**
     *  模糊查询
     */
    public static void queryByLike() throws IOException {

        SearchRequest request = new SearchRequest();

        request.indices("user");

        request.source(SearchSourceBuilder.searchSource().query(QueryBuilders.fuzzyQuery("name", "jack")));

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        for (SearchHit hit : response.getHits()) {
            System.out.println(hit.getSourceAsString());
        }
    }


    /**
     *  模糊查询
     */
    public static void queryByHighLighting() throws IOException {

        SearchRequest request = new SearchRequest();

        request.indices("user");

        HighlightBuilder highlightBuilder = new HighlightBuilder();

        highlightBuilder.preTags("<font color=\"red\">");
        highlightBuilder.postTags("</font>");
        highlightBuilder.field("name");

        SearchSourceBuilder builder = new SearchSourceBuilder();

        builder.highlighter(highlightBuilder);

        builder.query(QueryBuilders.termQuery("name", "jack"));

        request.source(builder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        for (SearchHit hit : response.getHits()) {
            System.out.println(hit.getSourceAsString() + "" + hit.getHighlightFields());
        }
    }

    /**
     *  聚合查询
     * @throws IOException
     */
    public static void queryByAgg() throws IOException {

        SearchRequest request = new SearchRequest();

        request.indices("user");

        request.source(SearchSourceBuilder.searchSource().aggregation(AggregationBuilders.max("maxBirthday").field("birthday")));

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        System.out.println(response.getAggregations().getAsMap());
    }



    public static void main(String[] args) throws IOException {
        // 创建文档
        //createDoc();

        // 更新文档
        //updateDoc();

        // 查询文档
        //queryDoc();

        // 删除文档
        //deleteDoc();

        // 批量操作
        //batchRequest();

        // match_all
        //queryMathAll();

        // 条件查询
        //queryMathWithCondition();

        // 分页查询
        //queryByPage();

        // 组合条件查询
        //queryByBool();

        // 范围查询
        //queryByRange();

        // 模糊查询
        // queryByLike();

        // 高亮查询
        //queryByHighLighting();

        // 聚合查询
        queryByAgg();

        client.close();
    }
}
